// Since Rust does not have packages in the same sense as Java,
// we do not need to declare a package at the top.
// However, we need to import necessary crates.

use std::sync::atomic::{AtomicUsize, Ordering};
use std::thread;

pub struct NamedThreadFactory {
    name_prefix: String,
    thread_count: AtomicUsize,
    group: Option<thread::Builder>, // We'll use thread::Builder to simulate a "group"
    daemon: bool,
    priority: u32,
}

impl NamedThreadFactory {
    /// Creates a new `NamedThreadFactory` with the given name prefix.
    pub fn new<S: Into<String>>(name_prefix: S) -> Self {
        NamedThreadFactory {
            name_prefix: name_prefix.into(),
            thread_count: AtomicUsize::new(0),
            group: None,
            daemon: false,
            priority: 1, // In Rust, the priority is not directly set on threads.
        }
    }

    /// Sets the thread group. Rust doesn't have thread groups, so we'll use thread::Builder.
    pub fn group(&mut self, _group: thread::Builder) -> &mut Self {
        self.group = Some(_group);
        self
    }

    /// Sets whether threads created by this factory should be daemon threads.
    pub fn daemon(&mut self, daemon: bool) -> &mut Self {
        self.daemon = daemon;
        self
    }

    /// Sets the priority of the threads. Note that priority is not directly applicable in Rust.
    pub fn priority(&mut self, _priority: u32) -> &mut Self {
        self.priority = _priority;
        self
    }

    /// Creates a new thread with the given closure.
    pub fn new_thread<F>(&self, f: F) -> thread::JoinHandle<()>
    where
        F: FnOnce() + Send + 'static,
    {
        let name = format!("{}{}", self.name_prefix, self.thread_count.fetch_add(1, Ordering::SeqCst));

        let builder = thread::Builder::new()
            .name(name.clone())
            .spawn(f)
            .expect("Failed to create thread");

        // Rust does not have a direct way to set a thread as daemon.
        // We would typically manage the lifetime of the thread through other means.
        builder
    }
}

// Example usage:
// A thread factory that creates named threads.
//
// # Examples
// ```
// let factory = NamedThreadFactory::new("worker-");
// let handle = factory.new_thread(|| {
//     println!("Hello from a named thread!");
// });
// handle.join().unwrap();
// ```